
#include <qDebug>
#include <QMutexLocker>
#include "entrenador.h"

Entrenador* Entrenador::instancia = NULL;

Entrenador::Entrenador() 
{
	proyecto = NULL;

    preferencias.deserializar();
    
    establecerPreferencias();

    connect(&midiIn, SIGNAL(mensajeRecibido(MensajeMidi)), this, SLOT(procesarMensajeRecibido(MensajeMidi)));
}

Entrenador::~Entrenador()
{
    preferencias.serializar();

	midiIn.cerrarPuerto();
}

Entrenador* Entrenador::getInstancia()
{
	if (instancia == NULL) {
		instancia = new Entrenador();
	}
	return instancia;
}

void Entrenador::destruir()
{
    if (instancia != NULL) {
        delete instancia;
        instancia = NULL;
    }
}

void Entrenador::establecerPreferencias()
{
    midiIn.abrirPuerto(preferencias.obtenerValor(PARAMETRO_MIDI_IN));
    interprete.setTempo(preferencias.obtenerValor(PARAMETRO_TEMPO).toInt());
    interprete.setReproducirSonidoMetronomo(preferencias.obtenerValor(PARAMETRO_REPRODUCIR_SONIDO_METRONOMO) != "0");
}

void Entrenador::arrancar()
{
	//qDebug("entrenador iniciado");

	notasUsuario.clear();
	notasEntrenamiento.clear();

	interprete.activar();
}

void Entrenador::parar()
{
	//qDebug("entrnador finalizado");

	interprete.desactivar();

	notasUsuario.clear();
	notasEntrenamiento.clear();
}



void Entrenador::marcarNotaUsuario(quint64 ms, const QString& nombreNota)
{
	//QMutexLocker locker(&mutexUsuario);
	notasUsuario.insert(nombreNota, ms);
}

void Entrenador::marcarNotaEntrenamiento(quint64 ms, const QString& nombreNota)
{
	//QMutexLocker locker(&mutexEntrenamiento);
	notasEntrenamiento.insert(nombreNota, ms);
}

QList<NotaRegistrada> Entrenador::getListaNotasRegistradasUsuario()
{
	return registroNotasUsuario.getListaNotas();
}

int Entrenador::getNivelNotaUsuario(const QString& nombreNota)
{
//	QMutexLocker locker(&mutexUsuario);
	if (!notasUsuario.contains(nombreNota)) {
		return 0;
	}
	quint64 msNota = notasUsuario.value(nombreNota);
	return getNivelSegunMilisegundos(msNota);
}

int Entrenador::getNivelNotaEntrenamiento(const QString& nombreNota)
{
//	QMutexLocker locker(&mutexEntrenamiento);
	if (!notasEntrenamiento.contains(nombreNota)) {
		return 0;
	}
	quint64 msNota = notasEntrenamiento.value(nombreNota);
	return getNivelSegunMilisegundos(msNota);
}

QColor Entrenador::getColorNota(int nota)
{
    return drumMap.getColorNota(nota);
}

QColor Entrenador::getColorNota(const QString& nombreNota)
{
    return drumMap.getColorNota(nombreNota);
}

int Entrenador::getNivelSegunMilisegundos(quint64 msNota)
{
	int nivel;
	quint64 msActual = getMilisegundosDesdeInicio();
	if (msActual > msNota + 255 || msActual < msNota) {
		nivel = 0;
	} else {
		nivel = 255 - msActual + msNota;
	}
	
	return nivel;
}

quint64 Entrenador::getMilisegundosDesdeInicio()
{
	return interprete.getMilisegundosDesdeInicio();
}

void Entrenador::procesarMensajeRecibido(MensajeMidi mensajeMidi)
{    
	if (mensajeMidi.getComando() == NOTE_ON) {
		//qDebug() << mensajeMidi.getNotaMidi();

		int nota = mensajeMidi.getNotaMidi();
		
		quint64 ms = getMilisegundosDesdeInicio();
		QString nombreNota = drumMap.getNombreNota(nota);

		marcarNotaUsuario(ms, nombreNota);
		registroNotasUsuario.registrar(ms, mensajeMidi.getNotaMidi(), mensajeMidi.getVelocidad());
	}
}

QString Entrenador::getNombreNota(int nota)
{
	return drumMap.getNombreNota(nota);
}

void Entrenador::setProyecto(Proyecto* proyecto)
{
	this->proyecto = proyecto;
}

void Entrenador::seleccionarCompas(int indiceCompas)
{
    if (proyecto == NULL) {
        return;
    }
    interprete.setCompas(proyecto->getCompas(indiceCompas));
    
}

//void Entrenador::actualizar()
//{
//	
//
//}